﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PSS4Publish.Repositories;
using PSS4Publish.Repositories.Domain;
using PSS4Publish.Common;

namespace PSS4Publish.AppConsole
{
    class Program
    {
        #region ArgumentParser helper Class
        class ArgumentParser
        {
            #region Parser Methods

            //Method which will parse the string input and return a hashtable
            public static Hashtable Parse(String[] args)
            {
                Hashtable argTable = new Hashtable();
                try
                {
                    string[] keyvalue;
                    string value;

                    if ((null == args) || args.Length == 0)
                    {
                        AddKeyValuePair(argTable, "Invalid", "true");
                        return argTable;
                    }


                    foreach (string s in args)
                    {

                        if (s.StartsWith("/") && (s.Contains("=") && !s.Contains("?")))
                        {
                            // Strip off "/"
                            string key = s.Substring(1, s.Length - 1);
                            keyvalue = key.Split('=');
                            key = keyvalue[0].ToString();
                            value = keyvalue[1].ToString();

                            if (value == null || value.Trim() == string.Empty)
                            {
                                AddKeyValuePair(argTable, "Invalid", "true");
                                return argTable;
                            }

                            AddKeyValuePair(argTable, key, value);

                        }
                        else
                        {
                            if (s.Contains("?"))
                            {
                                AddKeyValuePair(argTable, "?", "true");
                            }
                            else if (s.Contains("/AUTO") || s.Contains("-AUTO"))
                            {
                                AddKeyValuePair(argTable, "AUTO", "true");
                            }
                            else
                            {
                                // otherwise this is invalid value
                                AddKeyValuePair(argTable, "Invalid", "true");
                            }
                        }
                    }
                    // return the hashtable with the command line arguments in it.
                    return argTable;
                }
                catch (ArgumentOutOfRangeException outOfRangeEx)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Arguments out of range, please check error log" + outOfRangeEx.Message + Environment.NewLine + outOfRangeEx.StackTrace);
                    Console.ResetColor();
                    return argTable;
                }
                catch (Exception ex)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
                    Console.ResetColor();
                    return argTable;
                }
            }

            //Add the arguments in the form of a keyvalue pair to Hashtable
            public static void AddKeyValuePair(Hashtable argTable, string key, string value)
            {
                try
                {
                    if (!argTable.ContainsKey(key.ToUpper()))
                    {
                        // add this to table
                        argTable.Add(key.ToUpper(), value);
                    }
                    else
                    {
                        //substitute the value with the latest one
                        argTable[key.ToUpper()] = value;
                    }
                }
                catch (ArgumentException argEx)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine(argEx.Message + Environment.NewLine + argEx.StackTrace);
                    Console.ResetColor();
                }
                catch (Exception ex)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
                    Console.ResetColor();
                }
            }
            #endregion
        }
        #endregion

        #region Split Argument
        static int Main(string[] args)
        {
            try
            {
                return ParsingArgument(args);
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex.Message);
                Console.ResetColor();
            }

            return 1;
        }

        static int ParsingArgument(string[] args)
        {
            int successIndicator = 1;
            StringBuilder message = new StringBuilder();

            if (args.Length > 0)
            {
                Hashtable myargs = ParseArguments(args);
                successIndicator = CheckParameter(myargs);
                if (successIndicator > 0)
                {
                    successIndicator = ProgramSplitter(myargs, successIndicator);
                    if (successIndicator > 0)
                    {
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine("Program Run Successfuly.");
                        Console.ResetColor();
                        successIndicator = 0; // exit code for successful action
                    }
                }
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                message.AppendLine("No argument found. Type '?' for detail.");
                Console.WriteLine(message.ToString());
                Console.ResetColor();
                successIndicator = 1;// exit code for failed action
            }

            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine("Console Finished Running.");
            Console.ResetColor();

            return successIndicator;
        }

        static Hashtable ParseArguments(String[] args)
        {
            Hashtable myargs = new Hashtable();
            foreach (string s in args)
            {
                if ((s.StartsWith("/") || s.Contains("=") || s.Contains("?")))
                {
                    myargs = ArgumentParser.Parse(args);
                    break;
                }
            }
            return myargs;
        }

        static int CheckParameter(Hashtable args)
        {
            int programNumber = 0;

            StringBuilder errorMessage = new StringBuilder();
            errorMessage.Append("There was an error while parsing the arguments, please check usage syntax below.");

            if (args.ContainsKey("?"))
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(GenerateDefaultUsageSyntaxMessage());
                Console.ResetColor();
                return 0;
            }
            else if (args.ContainsKey("INVALID"))
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(errorMessage);
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(GenerateDefaultUsageSyntaxMessage());
                Console.ResetColor();
                return 0;
            }

            if (!args.ContainsKey("PE"))
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(errorMessage);
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(GenerateDefaultUsageSyntaxMessage());
                Console.ResetColor();
                return 0;
            }
            else
            {
                string progNum = args["PE"].ToString();

                if (!int.TryParse(progNum, out programNumber))
                {
                    Console.WriteLine(errorMessage);
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine(GenerateDefaultUsageSyntaxMessage());
                    Console.ResetColor();
                }
            }

            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine("Parameter Used:");
            foreach (DictionaryEntry arg in args)
            {
                Console.WriteLine(string.Format("{0}={1}", arg.Key, arg.Value));
            }
            Console.ResetColor();

            return programNumber;
        }

        static StringBuilder GenerateDefaultUsageSyntaxMessage()
        {
            StringBuilder usageSyntax = new StringBuilder();
            usageSyntax.Append("Syntax: " + System.Reflection.Assembly.GetEntryAssembly().GetName().Name + "/PE=n\n");
            usageSyntax.Append("1 : Untuk Memindahkan Hasil Build Dari CCNET ke Folder IIS");
            return usageSyntax;
        }
        #endregion

        static int ProgramSplitter(Hashtable args, int programNumber)
        {
            switch (programNumber)
            {
                case 1: // Untuk Memindahkan Hasil Build Dari CCNET ke Folder IIS
                    {
                        CruiseControlWrapper ccWrapper = new CruiseControlWrapper();
                        ResultStatus rs = ccWrapper.GetStatusPublish("", "");
                        PublishExecution execution = new PublishExecution();

                        if (rs.IsSuccess)
                            rs = execution.DeleteBackupFile();

                        if (rs.IsSuccess)
                            rs = execution.BackupConfig();

                        if (rs.IsSuccess)
                            rs = execution.CopyPublish();

                    }
                    break;
            }
            return 0;
        }



    }
}
